import 'package:flutter/material.dart';
import 'package:t3_data_service/data_provider/map_sctx/t3_map_sctx_provider.dart';
import 'package:t3_foundation/t3_foundation.dart';

import '../../map/core/t3_location.dart';

class T3RouteResultModel {
  /// 导航算路ID（只有腾讯地图时会返回，后面路线绑定需要传入）
  String? navSessionId;

  List<T3RouteModel> routes;

  /// 路线数据供应商类型。
  /// 注意，这里的供应商可能和算路入参时的传入的地图类型不一致。
  /// 比如首页使用高德地图渲染，但是算路接口异常时，服务端切换到腾讯，则此时的路线返回接口中的供应商类型还会变成腾讯；
  final T3MapType provider;

  T3RouteResultModel({
    required this.routes,
    required this.provider
  });

  /// 通过SDK驾车路线初始化
  static T3RouteResultModel? fromSDKRouteJson(Map<String, dynamic> json, T3MapType provider) {

    final error = json['error'];

    if (error is String && error.isNotEmpty) {
      debugPrint('error: $error');
      return null;
    }
    else {
      List<T3RouteModel> routes = [];
      
      final routesValue = json["routes"];
      if (routesValue is List) {
        for (var element in routesValue) {
          if (element is Map<String, dynamic>) {
            final value = T3RouteModel.fromSDKJson(element, provider);
            if (value != null) {
              routes.add(value);
            } 
          } 
        }
      }
      return T3RouteResultModel(routes: routes, provider: provider);
    }
  }

  @override
  String toString() {
    return 'routesCount: ${routes.length}, provider: ${provider.value}';
  }
}

///标准路线模型
class T3RouteModel {
  /// 路线id
  String? routeId;
  
  /// 预计行驶时间，单位：秒
  int duration;

  /// 起点和终点的距离，单位：米
  int distance;

  /// 道路费用，单位：元
  double tolls;

  /// 红绿灯数量，单位：个
  int trafficLightCount;

  /// 路线坐标点
  List<T3LocationCoordinate2D> coordinates;

  /// 方案标签，表明方案特色
  String? tag;
  /// 方案子标签，用于地图路线气泡的展示
  String? subTag;

  /// 路况数据
  String? traffic;

  /// 路线数据供应商类型。
  /// 注意，这里的供应商可能和算路入参时的传入的地图类型不一致。
  /// 比如首页使用高德地图渲染，但是算路接口异常时，服务端切换到腾讯，则此时的路线返回接口中的供应商类型还会变成腾讯；
  final T3MapType provider;

  T3RouteModel({
    required this.routeId,
    required this.duration,
    required this.distance,
    required this.tolls,
    required this.trafficLightCount,
    required this.tag,
    required this.subTag,
    required this.coordinates,
    this.traffic,
    required this.provider
    });

  @override
  String toString() {
    return "routeId: $routeId, duration: $duration, distance: $distance, tolls: $tolls, trafficLightCount: $trafficLightCount";
  }

  static List<T3LocationCoordinate2D> stringToCoordinate2D({required String polyline}) {
    List<String> polylines = polyline.split(';');
    List<T3LocationCoordinate2D> coordinates = [];
    for (var element in polylines) {
        List<String> location = element.split(',');
        if(location.length > 1) {
          final longitude = DoubleUtils.dynamicToNullDouble(location[0]);
          final latitude = DoubleUtils.dynamicToNullDouble(location[1]);
          if (longitude != null && latitude != null) {
            coordinates.add(T3LocationCoordinate2D(longitude: longitude, latitude: latitude));
          }
        }
      }
    return coordinates;
  }

  static T3RouteModel? fromSDKJson(Map<String, dynamic> json, T3MapType provider) {

    final error = json['error'];

    if (error is String && error.isNotEmpty) {
      debugPrint('error: $error');
      return null;
    }
    else {
      final duration = IntUtils.dynamicToNullInt(json["duration"]);
      final distance = IntUtils.dynamicToNullInt(json["distance"]);
      final tolls = DoubleUtils.dynamicToNullDouble(json["tolls"]) ?? 0;
      final trafficLightCount = IntUtils.dynamicToNullInt(json["trafficLightCount"]) ?? 0;
      final polyline = StringUtils.dynamicToString(json["polyline"]);
      final tag = StringUtils.dynamicToString(json["tag"]);

      if (duration != null && distance != null && polyline != null) {

        List<T3LocationCoordinate2D> coordinates = T3RouteModel.stringToCoordinate2D(polyline: polyline);
        final route = T3RouteModel(
                                    routeId: null, 
                                    duration: duration, 
                                    distance: distance, 
                                    tolls: tolls, 
                                    trafficLightCount: trafficLightCount, 
                                    tag: tag,
                                    subTag: null,
                                    coordinates: coordinates, 
                                    provider: provider);
        return route;
      }
      else {
        return null;
      }
    }
  }
}